<template>
  <div class="server-main">
    <el-form :inline="true" v-model="modelData" class="search-form">
      <el-form-item label="数据源名称:" class="form-input">
        <el-input v-model.trim="modelData.dataSourceName" clearable></el-input>
      </el-form-item>
      <el-form-item label="状态:" class="form-input">
        <el-select v-model="modelData.state">
          <el-option
            v-for="item in dropDownDataList"
            :key="item.key"
            :value="item.key"
            :label="item.value"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button id="btn" type="primary" size="small" @click="onSubmit(1)"
          >查询</el-button
        >
      </el-form-item>
    </el-form>

    <div class="server-table">
      <div class="table-title">
        <span class="table-title-text">数据源管理</span>
        <div>
          <el-button type="primary" size="small" @click="createDataSource"
            >新增数据源</el-button
          >
        </div>
      </div>
      <el-table
        :data="tableList"
        :cell-style="{ color: '#333333' }"
        :header-cell-style="{ background: '#F3F4F7', color: '#000000' }"
      >
        <el-table-column
          type="index"
          label="ID"
          width="50"
          align="center"
          fixed="left"
        ></el-table-column>
        <el-table-column
          prop="dataSourceName"
          label="数据源名称"
          align="center"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          prop="dataSourceType"
          label="数据源类型"
          align="center"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          prop="dataBaseAddress"
          label="数据源地址"
          align="center"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          prop="userName"
          label="访问用户名"
          align="center"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          prop="createName"
          label="创建人"
          align="center"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          prop="createTime"
          label="创建时间"
          align="center"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          prop="dataSourceStatus"
          label="状态"
          width="200"
          align="center"
        >
          <template slot-scope="scope">
            <i
              class="little-circle-blue"
              v-if="scope.row.dataSourceStatus === '启用'"
            ></i>
            <i class="little-circle-red" v-else></i>
            <span>{{
              scope.row.dataSourceStatus === "启用" ? "启用" : "禁用"
            }}</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" fixed="right" align="center" width="200">
          <template slot-scope="scope">
            <el-link
              :underline="false"
              type="primary"
              class="ontology-edit"
              @click.native.prevent="updateDataSource(scope.row)"
              >编辑</el-link
            >
            <el-link
              :underline="false"
              type="primary"
              class="ontology-edit"
              @click.native.prevent="changeStatus(scope.row)"
              >{{ scope.row.dataSourceStatus === "启用" ? "禁用" : "启用" }}
            </el-link>
            <el-link
              :underline="false"
              type="primary"
              class="ontology-edit"
              @click.native.prevent="deleteData(scope.row)"
              >删除</el-link
            >
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        background
        small
        layout="total, prev, pager, next, sizes, jumper"
        :page-sizes="[10, 20, 30]"
        :total="total"
        :hide-on-single-page="!total"
        :page-size.sync="modelData.pageSize"
        :pager-count="7"
        :current-page="modelData.pageNum"
        @current-change="handleCurrentChange"
        @size-change="handleSizeChange"
      >
      </el-pagination>
    </div>

    <!-- 弹窗 -->
    <el-dialog
      :title="title"
      :visible.sync="dialogVisible"
      @close="afterDialogClose()"
      width="50%"
      class="dataSourceDialog"
    >
      <el-form
        :model="modelParams"
        :rules="titleRules"
        ref="dialogTitleForm"
        label-position="right"
        label-width="120px"
      >
        <el-row :gutter="40">
          <el-col :span="11">
            <el-form-item label="数据源名称:" prop="dataSourceName">
              <el-input v-model="modelParams.dataSourceName"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="11">
            <el-form-item label="数据源类型:" prop="dataSourceType">
              <el-select
                v-model="modelParams.dataSourceType"
                :disabled="title === '编辑数据源'"
                @change="changeDataSourceType"
              >
                <el-option
                  v-for="item in dataSourceTypeList"
                  :key="item.key"
                  :value="item.key"
                  :label="item.value"
                >
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <el-row>
        <el-col :style="{ paddingLeft: '34px', fontWeight: 600 }"
          >数据源配置</el-col
        >
      </el-row>

      <el-form
        :model="modelParams"
        :rules="contentRules"
        ref="dialogContentForm"
        label-position="right"
        label-width="120px"
      >
        <template v-if="modelParams.dataSourceType !== 'EXCEL'">
          <el-row :gutter="40">
            <el-col :span="11" v-for="item in dataConfig" :key="item.filedKey">
              <el-form-item
                :label="`${item.filedValue}:`"
                :prop="`${item.filedKey}`"
              >
                <el-input
                  v-model="item[item.filedKey]"
                  :type="item.filedValue == '密码' ? 'password' : 'text'"
                  :show-password="item.filedValue == '密码' ? true : false"
                >
                </el-input>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="22">
              <el-form-item label="连接地址:" prop="connectAddress">
                <el-input
                  v-model="connectAddress"
                  readonly="readonly"
                ></el-input>
              </el-form-item>
            </el-col>
          </el-row>
        </template>

        <template v-else>
          <el-row :gutter="40">
            <el-col :span="11">
              <el-form-item label="文件:">
                <p>{{ this.modelParams.dataBaseName }}</p>
                <!-- :show-file-list="true"  -->
                <el-upload
                  class="upload-demo"
                  ref="upload"
                  action="#"
                  :show-file-list="false"
                  :on-change="beforeUpload"
                  :auto-upload="false"
                >
                  <el-button
                    v-if="title === '新增数据源'"
                    slot="trigger"
                    size="small"
                    type="primary"
                    >选择文件</el-button
                  >
                  <el-button v-else slot="trigger" size="small" type="primary"
                    >重新上传</el-button
                  >
                  <el-button
                    :style="{ marginLeft: '10px' }"
                    v-if="title === '编辑数据源'"
                    size="small"
                    type="primary"
                  >
                    <el-link
                      :underline="false"
                      :style="{ color: 'white' }"
                      :href="`${$api.dataSourceManagement.download}?id=${this.currentId}`"
                      >下载文件</el-link
                    >
                  </el-button>
                </el-upload>
              </el-form-item>
            </el-col>
          </el-row>
        </template>
      </el-form>

      <div slot="footer" class="dialog-footer">
        <el-button @click="resetDialogForm">关 闭</el-button>
        <el-button
          v-if="modelParams.dataSourceType !== 'EXCEL'"
          @click="testConnection"
          :loading="loadingTest"
          >连接测试
        </el-button>
        <el-button type="primary" @click="submitDialogForm" :loading="loading"
          >确 定</el-button
        >
      </div>
    </el-dialog>
  </div>
</template>
<script>
export default {
  name: "DataSourceManagement",
  components: {},
  data: () => {
    return {
      modelData: {
        dataSourceName: "", // 数据源名称
        state: "", // 状态 0 启用，1禁用，全部
        pageNum: 1, // 页码
        pageSize: 10, // 每页条数
      },
      currentId: "", // 当前编辑项的 id
      dropDownDataList: [], // 状态下拉框选项
      dataSourceTypeList: [], // 数据源类型
      tableList: [], // 数据源列表
      total: 0, // 数据总条数
      loading: false, // 确定按钮的加载状态
      loadingTest: false, // 连接测试按钮的加载状态
      dialogVisible: false,
      title: "新增数据源",
      modelParams: {
        dataSourceName: "", // 数据源名称
        dataSourceType: "", // 数据源类型
        dataBaseName: "", //上传文件名称
      },
      connectAddress: "", // 连接地址
      titleRules: {
        name: [
          {
            required: true,
            message: "请输入本体类名称",
            trigger: "blur",
          },
        ],
      },
      contentRules: {
        name: [
          {
            required: true,
            message: "请输入本体类名称",
            trigger: "blur",
          },
        ],
      },
      dataConfig: [],
      currentDataSource: null, // 当前编辑项的数据
      file: null, // 当前将要上传的文件
    };
  },
  computed: {
    modelParamsJson() {
      this.dataConfig.forEach((item) => {
        this.modelParams[item.filedKey] = this.dataConfig[item.filedKey];
      });
      return JSON.parse(JSON.stringify(this.modelParams));
    },
  },
  watch: {
    modelParamsJson: {
      handler(newVal, oldVal) {
        const { dataSourceIp, dataSourcePort, dataSourceType, dataBaseName } =
          newVal;
        // this.connectAddress = `${dataSourceType}://${dataSourceIp}:${dataSourcePort}/${dataBaseName}`;
      },
      deep: true,
    },
    dataConfig: {
      handler(newVal, oldVal) {
        let res = {};
        newVal.forEach((item) => {
          Object.assign(res, {
            [`${item.filedKey}`]: item[item.filedKey],
          });
        });
        const { dataSourceIp, dataSourcePort, dataBaseName } = res;
        const { dataSourceType } = this.modelParams;
        this.connectAddress = `${dataSourceType}://${dataSourceIp}:${dataSourcePort}/${dataBaseName}`;
      },
      deep: true,
    },
  },

  created() {
    this.getDropDownDataList({
      source: 1,
      code: "EnableState",
    });
    this.getDataSourceList();
  },
  methods: {
    async getDropDownDataList(params) {
      let res = await this.$axios.post(
        this.$api.dataSourceManagement.getDropDownDataList,
        params
      );
      const { data, message, code } = res.data;
      if (code !== 200) {
        this.$message.error("出错了!");
        return;
      }
      if (params.source === 1) {
        data.unshift({
          value: "全部",
          key: 2,
        });
        this.dropDownDataList = data;
      } else if (params.source === 2) {
        this.dataSourceTypeList = data;
      }
    },

    // 获取数据源列表
    async getDataSourceList() {
      const {
        pageNum,
        pageSize,
        state: dataSourceStatusCode,
        dataSourceName,
      } = this.modelData;
      let params = {
        dataSourceStatusCode:
          dataSourceStatusCode === 2 ? null : dataSourceStatusCode,
        dataSourceName,
        pageNum,
        pageSize,
      };
      let res = await this.$axios.post(
        this.$api.dataSourceManagement.getDataSourceList,
        params
      );
      const { data, message, code } = res.data;
      this.tableList = data.list;
      this.total = data.totalCount;
      this.modelData.pageNum = data.pageNum;
      this.modelData.pageSize = data.pageSize;
    },
    // 查询
    onSubmit(pageNum) {
      this.modelData.pageNum = pageNum ? pageNum : this.modelData.pageNum;
      this.getDataSourceList();
    },
    // 修改当前页码
    handleCurrentChange(page) {
      this.modelData.pageNum = page;
      this.getDataSourceList();
    },
    // 修改每页条数
    handleSizeChange(e) {
      this.modelData.pageSize = e;
      this.getDataSourceList();
    },
    // 删除数据
    deleteData(item) {
      this.$confirm(
        "是否确认将此数据源删除？删除后不可恢复，请谨慎操作。",
        "提示",
        {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }
      )
        .then(() => {
          this.deleteFun(item.dataSourceId);
        })
        .catch(() => {});
    },
    // 调用删除接口的方法
    async deleteFun(id) {
      let res = await this.$axios.post(
        `${this.$api.dataSourceManagement.deleteDataSource}?id=${id}`
      );
      const { data, message, code } = res.data;
      if (code !== 200) {
        this.$message.error(message);
        return;
      }
      this.$message.success(data);
      // 删除完成后在调用一次查询接口
      this.getDataSourceList();
    },

    // 修改状态
    changeStatus(item) {
      let { dataSourceId: id, dataSourceStatus } = item;
      if (dataSourceStatus === "启用") {
        // 点击禁用时
        this.$confirm("是否确认停用此数据源？", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        })
          .then(() => {
            this.disableDataSource(id);
          })
          .catch(() => {});
      } else {
        this.$confirm("是否确认启用此数据源？", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        })
          .then(() => {
            this.enableDataSource(id);
          })
          .catch(() => {});
      }
    },
    disableDataSource(id) {
      this.$axios
        .post(`${this.$api.dataSourceManagement.disableDataSource}?id=${id}`)
        .then((res) => {
          if (res.data.code !== 200) {
            this.$message.warning(res.data.message);
            return;
          }
          this.$message.success("状态更改成功");
          this.onSubmit();
        })
        .catch((err) => {
          this.$message.warning("状态更改失败");
          console.error(err);
        });
    },
    enableDataSource(id) {
      this.$axios
        .post(`${this.$api.dataSourceManagement.enableDataSource}?id=${id}`)
        .then(() => {
          this.$message.success("状态更改成功");
          this.onSubmit();
        })
        .catch((err) => {
          this.$message.warning("状态更改失败");
          console.error(err);
        });
    },

    // 获取单个数据源信息
    async getItemDataSource(currentId) {
      let res = await this.$axios.post(
        `${this.$api.dataSourceManagement.getDataSource}?id=${currentId}`
      );
      const { data, message, code } = res.data;
      if (code !== 200) {
        this.$message.warning(message);
        return;
      }
      this.currentDataSource = data;
      this.modelParams.dataSourceName = data.dataSourceName;
      this.modelParams.dataBaseName = data.dataBaseName;
      this.modelParams.dataSourceType = data.dataSourceType;
    },

    // 编辑数据源
    async updateDataSource(row) {
      this.currentId = row.dataSourceId;
      this.title = "编辑数据源";
      await this.getItemDataSource(this.currentId);
      await this.loadConInfoFiled(row.dataSourceType);

      this.dialogVisible = true;
    },

    // 模态框关闭后
    afterDialogClose() {
      this.$refs["dialogTitleForm"].resetFields();
      this.loading = false;
    },

    // 取消
    resetDialogForm() {
      this.dialogVisible = false;
    },

    // 打开新增本体框
    createDataSource() {
      this.title = "新增数据源";
      this.loadConInfoFiled();
      this.dialogVisible = true;
      this.getDropDownDataList({
        source: 2,
        code: "data_source_type",
      });
    },

    changeDataSourceType(e) {
      this.loadConInfoFiled(e);
    },

    async loadConInfoFiled(arg) {
      let params = {
        code: arg || "",
      };
      let res = await this.$axios.post(
        this.$api.dataSourceManagement.loadConInfoFiled,
        params
      );
      const { code, message, data } = res.data;
      if (code !== 200) {
        this.$message.error(message);
        return;
      }
      if (this.title == "新增数据源") {
        data.forEach((item) => {
          item[item.filedKey] = "";
        });
        this.dataConfig = data;
      } else {
        this.currentDataSource &&
          data.forEach((item) => {
            item[item.filedKey] = this.currentDataSource[item.filedKey];
            // item[item.filedKey] = "";
          });
        this.dataConfig = data;
      }
    },

    getDataConfig() {
      let dataParams = {};
      this.dataConfig.forEach((item) => {
        Object.assign(dataParams, {
          [`${item.filedKey}`]: item[item.filedKey],
        });
      });
      return dataParams;
    },

    // 连接测试
    async testConnection() {
      const { dataSourceName, dataSourceType } = this.modelParams;
      let dataParams = this.getDataConfig();
      const { dataSourceIp, dataSourcePort, dataBaseName, userName, password } =
        dataParams;

      let params = {
        dataSourceName,
        dataSourceType,
        dataSourceIp,
        dataSourcePort,
        dataBaseName,
        userName,
        password,
      };
      this.loadingTest = true;
      let res = await this.$axios.post(
        this.$api.dataSourceManagement.testConnection,
        params
      );
      const { data, message, code } = res.data;
      if (code !== 200) {
        this.$message.warning(message);
        this.loadingTest = false;
        return;
      }
      this.loadingTest = false;
      if (data == "连接失败") {
        this.$message.warning("无法连接指定ip的数据源，请检查ip地址或端口！");
        return;
      }
      this.$message.success(data);
    },

    async editDataSource() {
      let dataParams = this.getDataConfig();
      const { dataSourceIp, dataSourcePort, dataBaseName, userName, password } =
        dataParams;
      const { dataSourceName, dataSourceType } = this.modelParams;
      let params = {
        id: this.currentId,
        dataSourceName,
        dataSourceType,
        dataSourceIp,
        dataSourcePort,
        dataBaseName,
        userName,
        password,
      };
      let res = await this.$axios.post(
        this.$api.dataSourceManagement.editDataSource,
        params
      );
      const { data, message, code } = res.data;
      if (code !== 200) {
        this.$message.warning(message);
        this.loading = false;
        return;
      }
      this.loading = false;
      this.dialogVisible = false;
      this.$message.success(data);
      this.getDataSourceList();
    },

    // 确定
    submitDialogForm() {
      if (this.title === "新增数据源") {
        if (this.modelParams.dataSourceType !== "EXCEL") {
          this.addDataSource();
          return;
        }
        this.addDataSourceFile();
        return;
      } else {
        if (this.modelParams.dataSourceType !== "EXCEL") {
          this.editDataSource();
          return;
        }
        this.addDataSourceFile();
      }
    },

    // 新增数据源
    async addDataSource() {
      let dataParams = this.getDataConfig();
      const { dataSourceIp, dataSourcePort, dataBaseName, userName, password } =
        dataParams;
      const { dataSourceName, dataSourceType } = this.modelParams;
      let params = {
        dataSourceName,
        dataSourceType,
        dataSourceIp,
        dataSourcePort,
        dataBaseName,
        userName,
        password,
      };
      this.loading = true;
      let res = await this.$axios.post(
        this.$api.dataSourceManagement.addDataSource,
        params
      );
      const { data, message, code } = res.data;
      if (code !== 200) {
        this.$message.warning(message);
        this.loading = false;
        return;
      }
      this.loading = false;
      this.dialogVisible = false;
      this.$message.success(data);
      this.getDataSourceList();
    },

    async beforeUpload(file) {
      this.file = file.raw;
      const formData = new FormData();
      formData.append("file", file.raw);
      let res = await this.$axios.post(
        this.$api.dataSourceManagement.uploadExcel,
        formData
      );
      const { code, message, data } = res.data;
      this.file = data;
      if (code !== 200) {
        this.$message.error(message);
        return;
      }
      this.$message.success("上传成功");
    },

    async addDataSourceFile() {
      const { dataSourceName, dataSourceType } = this.modelParams;
      let params = {
        dataSourceName,
        dataSourceType,
        ...this.file,
      };
      this.loading = true;
      let res;
      if (this.title === "新增数据源") {
        res = await this.$axios.post(
          this.$api.dataSourceManagement.addExcelFile,
          params
        );
      } else {
        params = {
          ...params,
          id: this.currentId,
        };
        res = await this.$axios.post(
          this.$api.dataSourceManagement.editExcelFile,
          params
        );
      }
      const { data, message, code } = res.data;
      if (code !== 200) {
        this.$message.warning(message);
        this.loading = false;
        return;
      }
      this.loading = false;
      this.dialogVisible = false;
      this.$message.success(data);
      this.getDataSourceList();
    },

    // async download() {
    //   let res = await this.$axios.post(`${this.$api.dataSourceManagement.download}?id=${this.currentId}`);
    //   let response = new Blob([res], {
    //     type: res.headers['content-type']
    //   });
    //   let nameData = res.headers['content-disposition'];
    //   nameData = nameData.match(/filename=(.*)/)[1];
    //   const url = URL.createObjectURL(response);
    //   const a = document.createElement("a");
    //   a.style.display = "none";
    //   a.href = url;
    //   a.download = nameData;
    //   document.body.appendChild(a);
    //   a.click();
    //   document.body.removeChild(a);
    //   URL.revokeObjectURL(url);
    // },
  },
};
</script>
<style lang="scss" scoped>
.server-main {
  position: relative;

  .search-form {
    padding: 16px 32px;
    border-radius: 4px;
    background: #ffffff;

    .el-form-item {
      margin-bottom: 0;
    }

    .form-input {
      margin-right: 32px;

      /deep/ .el-input__inner {
        width: 240px;
        height: 32px;
        background: #ffffff;
        border-radius: 2px;
        border: 1px solid #e0e0e0;
      }
    }

    .el-select {
      /deep/ .el-input__inner {
        width: 240px;
        height: 32px;
        background: #ffffff;
        border-radius: 2px;
        border: 1px solid #e0e0e0;
      }
    }
  }

  .dataSourceDialog {
    .el-select {
      width: 92%;

      /deep/ .el-input__inner {
        width: 100%;
      }
    }
  }

  .server-table {
    margin-top: 16px;
    padding: 16px 32px 64px;
    border-radius: 4px;
    background: #ffffff;

    .table-title {
      display: flex;
      justify-content: space-between;
      align-items: center;

      .table-title-text {
        border-left: 5px solid $--color-primary;
        padding-left: 10px;
        margin: 8px 0;
        font-size: 16px;
        line-height: 16px;
      }

      margin-bottom: 10px;
    }

    .little-circle-blue {
      display: inline-block;
      width: 6px;
      height: 6px;
      border-radius: 3px;
      background: #55c898;
      position: relative;
      right: 4px;
      top: -2px;
    }

    .little-circle-red {
      display: inline-block;
      width: 6px;
      height: 6px;
      border-radius: 3px;
      background: #ee5564;
      position: relative;
      right: 6px;
      top: -2px;
    }
  }

  .ontology-edit {
    padding: 0 10px;

    & + .ontology-edit {
      border-left: 1px solid #dddddd;
    }
  }

  /deep/ .el-table__append-wrapper {
    padding: 10px;
  }

  .el-pagination {
    float: right;
    margin-top: 20px;

    .form-input /deep/ .el-input {
      width: 200px;
    }

    /deep/ .el-input__inner {
      height: 22px;
    }
  }

  /deep/ .el-dialog {
    width: 500px;
    border-radius: 5px;

    .el-dialog__body {
    
      .el-form-item {
        .el-cascader {
          width: 300px;
        }
      }
    }
  }
}
</style>
